<?php

namespace App\Http\Controllers;

use App\Http\Resources\OrderCollection;
use App\Map;
use App\Order;
use App\Support\Excel;
use App\Type;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;

class ExcelController extends Controller {
	protected $order, $excel;

	public function __construct(Order $order, Excel $excel) {
		$this->order = $order;
		$this->excel = $excel;
	}

	public function upload(Map $map, Type $type, Request $request) {
		$file = $request->file('file');
		if (!$file->isValid()) {
			return ['code' => 1, 'msg' => "nothing be upload"];
		}
		if ($map->type_id != $type->id) {
			return ['code' => 1, 'msg' => "no the Related"];
		}
		$append_data = ['map_id' => $map->id, 'created_at' => date('Y-m-d H:i:s'),
			'updated_at' => date('Y-m-d H:i:s')];
		//获取该渠道对应的映射关系
		$roles = $type->relation;
		if (!$roles) {
			return json_encode(['code' => 422, 'msg' => '该渠道没有对应的映射规则']);
		}
		$roles = $roles->toArray();
		unset($roles['type_id']);
		//上传
		$ext = $file->getClientOriginalExtension();
		$real_path = $file->getRealPath();
		$type = $file->getClientMimeType();
		$file_name = date('Y-m-d-H-i-s') . '-' . uniqid() . '.' . $ext;
		$bool = Storage::disk('excels')->put($file_name, file_get_contents($real_path));
		if (!$bool) {
			abort(500, 'file move fail');
		}
		$filePath = storage_path('app/public/excels/' . $file_name);
		//获取已存在的订单id及已存在的手机号码
		list($existOrderId, $existPhone) = $this->getExistData($map->id);
		//定义错误数据
		$errorData = [];

		$list = $this->excel->readExcel($filePath, $roles);
		$chuck_list = [];
		$num = 0;
		foreach ($list as $key => $value) {
			if (in_array("", $value)) {
				$value['error'] = "该条数据有必须值为空";
				array_push($errorData, $this->formatData($value));
				continue;
			}
			if (!preg_match("/^1[345678]{1}\d{9}$/", $value['phone'])) {
				$value['error'] = "该条数据手机号格式不正确";
				array_push($errorData, $this->formatData($value));
				continue;
			}
			if (in_array($value['phone'], $existPhone)) {
				$value['error'] = "该活动下已存在该手机号";
				array_push($errorData, $this->formatData($value));
				continue;
			} else {
				array_push($existPhone, $value['phone']);
			}
			if (in_array($value['order_id'], $existOrderId)) {
				$value['error'] = "该活动下已存在该订单号";
				array_push($errorData, $this->formatData($value));
				continue;
			} else {
				array_push($existPhone, $value['order_id']);
			}
			if ($num == 30) {
				DB::table('orders')->insert($chuck_list);
				$num = 1;
				$chuck_list = [array_merge($this->formatData($value), $append_data)];
			} else {
				array_push($chuck_list, array_merge($this->formatData($value), $append_data));
			}
			$num++;
		}
		if (!empty($chuck_list)) {
			$result = DB::table('orders')->insert($chuck_list);
		}
		if (!empty($errorData)) {
			session(['errorData' => $errorData]);
			$view = view('orders.error', compact('errorData'));
			return json_encode(['code' => 0, 'msg' => '数据导入成功', 'html' => response($view)->getContent()]);
		}
		return json_encode(['code' => 0, 'msg' => '数据导入成功']);
	}

	public function export($ids) {
		if ($ids != 'all') {
			if (!is_numeric($ids)) {
				$ids_list = array_merge(array_filter(explode(',', $ids), function ($value) {
					return is_numeric($value);
				}));
				if (empty($ids_list)) {
					abort(404);
				}
			}
		}
		$where = $ids == 'all' ? session('order-list-where') : ' id in (' . $ids . ')';
		$list = new OrderCollection($this->order->whereRaw($where)->get()->load('map'));

		if (empty($list)) {
			return ['code' => 1, 'msg' => 'nothing be checked'];
		}
		$list = json_decode(json_encode($list), true);

		$this->excel->exportExcel($list, $this->getFields(), date('Y-m-d') . '导出.xls');
	}

	public function exportError() {
		if (!session('?errorData')) {
			echo "<script>window.close()</script>";
		}
		$list = session('errorData');
		session(['errorData' => null]);
		$this->excel->exportExcel($list, $this->getErrorFields(), date('Y-m-d') . '错误数据导出.xls');
	}

	public function getExistData($map_id) {
		$list = (new Order)->where('map_id', $map_id)->get();
		$existOrderId = $existPhone = [];
		if ($list) {
			$list = $list->toArray();
			$existOrderId = array_column($list, 'order_id');
			$existPhone = array_column($list, 'phone');
		}
		return [$existOrderId, $existPhone];
	}

	private function formatData(array $data) {
		foreach ($data as $key => $value) {
			if ($key == 'order_time') {
				$data[$key] = $this->formatTime($value);
			}
		}
		return $data;
	}

	private function formatTime($value) {
		$time = is_numeric($value) ? ($value - 25569) * 24 * 60 * 60 : strtotime($value);
		if (!$time) {
			return '';
		}
		return date('Y-m-d H:i:s', $time);
	}

	private function getFields() {
		return [
			'A' => [
				'key' => 'order_id',
				'title' => '订单id',
			], 'B' => [
				'key' => 'contacts',
				'title' => '买家会员名',
			], 'C' => [
				'key' => 'channel',
				'title' => '渠道',
			], 'D' => [
				'key' => 'activity',
				'title' => '活动名',
			], 'E' => [
				'key' => 'products',
				'title' => '商品信息',
			], 'F' => [
				'key' => 'receipt_name',
				'title' => '收货人',
			], 'G' => [
				'key' => 'receipt_address',
				'title' => '收货地址',
			], 'H' => [
				'key' => 'phone',
				'title' => '联系方式',
			], 'I' => [
				'key' => 'price',
				'title' => '订单金额',
			], 'J' => [
				'key' => 'type',
				'title' => '订单状态',
			], 'K' => [
				'key' => 'order_time',
				'title' => '订单创建时间',
			], 'L' => [
				'key' => 'created_at',
				'title' => '订单导入时间',
			],
		];
	}

	private function getErrorFields() {
		return [
			'A' => [
				'key' => 'order_id',
				'title' => '订单id',
			], 'B' => [
				'key' => 'contacts',
				'title' => '买家会员名',
			], 'C' => [
				'key' => 'products',
				'title' => '商品信息',
			], 'D' => [
				'key' => 'receipt_name',
				'title' => '收货人',
			], 'E' => [
				'key' => 'receipt_address',
				'title' => '收货地址',
			], 'F' => [
				'key' => 'phone',
				'title' => '联系方式',
			], 'G' => [
				'key' => 'price',
				'title' => '订单金额',
			], 'H' => [
				'key' => 'order_time',
				'title' => '订单创建时间',
			], 'I' => [
				'key' => 'error',
				'title' => '错误原因',
			],
		];
	}

}
